package it.antonio.ilpizze.swing;

import it.antonio.ilpizze.ioc.Construction;
import it.antonio.ilpizze.ioc.Decoration;
import it.antonio.ilpizze.ioc.Dependencies;
import it.antonio.ilpizze.ioc.Module;
import it.antonio.ilpizze.reflection.Clazz;
import it.antonio.ilpizze.reflection.MethodAccessor;
import it.antonio.ilpizze.swing.event.Event;
import it.antonio.ilpizze.swing.event.EventDispatcher;
import it.antonio.ilpizze.swing.event.EventMap;
import it.antonio.ilpizze.swing.resource.Resources;
import it.antonio.ilpizze.swing.session.SessionStateCreator;
import it.antonio.ilpizze.swing.session.SessionStorage;
import it.antonio.ilpizze.swing.util.Converters;

import java.util.List;
import java.util.ResourceBundle;

public abstract class SwingModule extends Module {

	@Override
	public void configure() {
		
		final EventMap eventMap = new EventMap();
		allObjects(new Decoration<Object>() {

			@Override
			public void decorate(Object instance, Dependencies dependencies) {
				Clazz<?> clazz = Clazz.get(instance.getClass());
				List<MethodAccessor> methods = clazz.findMethodsWithAnnotation(Event.class);
				for (MethodAccessor method : methods) {
					eventMap.subscribe(method, instance);
				}
			}
		});

		object(EventDispatcher.class, new Construction<EventDispatcher>() {

			@Override
			public EventDispatcher construct(Class<? extends EventDispatcher> type, Dependencies dependencies) {
				return new EventDispatcher(eventMap);
			}
		});

		object(Resources.class, new Construction<Resources>() {

			@Override
			public Resources construct(Class<? extends Resources> type, Dependencies dependencies) {

				ResourceBundle resourceBundle = ResourceBundle.getBundle("resources");

				return new Resources(dependencies.getCallingClass(), resourceBundle, new Converters());
			}

		});

		object(SessionStorage.class, autowireConstructor());
		object(SessionStateCreator.class, emptyConstructor());

		swingConfigure();

	}

	protected abstract void swingConfigure();

}
